<!---
	Copyright 2010 Edward Trudeau, Jeremy Battle
    This software is freely available under the MIT License: http://www.opensource.org/licenses/mit-license.php
    http://ayc.googlecode.com
    
--->

<cfcomponent output="false" hint="I build singleton components and hold references to them in my instances structure.">
	<!--- properties for documenting purposes --->
	<cfproperty name="instances" type="struct" hint="The structure that holds all instances of singleton components built by the factory"  />

	<cfset variables.instances = structNew()>
	<cfset variables.cfcPath = "" />
	<cfset variables.configurator = "" />
	
	<cffunction name="init" returntype="appFactory" output="false">
		<cfargument name="cfcPath" type="string" required="yes" default="" />
		<cfargument name="configurator" type="configurator" required="yes" />
		
		<cfset variables.cfcPath = arguments.cfcPath />
		<cfset variables.configurator = arguments.configurator />
		
		<cfset application.msg = "appFactory built." />
		<cfreturn this />
	</cffunction>
	
	<cffunction name="getConfig" returntype="struct" hint="I return the current config">
		<cfreturn variables.config />
	</cffunction>
	
	<cffunction name="getComponent" returnType="any" output="false">
		<cfargument name="name" type="string" required="true">
        
        <cfset var tmpDAO = "" />
        <cfset var tmpGW = "" />
        <cfset var tmpOTsvc = "" />
		
		<cfswitch expression="#arguments.name#">
		
			<cfcase value="authenticator">
				<cfreturn createObject("component", "Authenticator").init(variables.configurator)>
			</cfcase>
			<cfcase value="validator">
				<cfreturn createObject("component", "Validator").init()>
			</cfcase>
			<cfcase value="FieldService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Field.FieldDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Field.FieldGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.Field.FieldService").init(tmpDAO, tmpGW, get("ValidationService"), get("QuestionService"), get("OptionService")) />
			</cfcase>
			<cfcase value="ValidationService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Validation.ValidationDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Validation.ValidationGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.Validation.ValidationService").init(tmpDAO, tmpGW) />
			</cfcase>
			<cfcase value="QuestionService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Field.QuestionDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Field.QuestionGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.Field.QuestionService").init(tmpDAO, tmpGW) />
			</cfcase>
			<cfcase value="OptionService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Field.OptionDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Field.OptionGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.Field.OptionService").init(tmpDAO, tmpGW) />
			</cfcase>
			<cfcase value="PageService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Page.PageDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Page.PageGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.Page.PageService").init(tmpDAO, tmpGW) />
			</cfcase>
			<cfcase value="WizardService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Wizard.WizardDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Wizard.WizardGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.Wizard.WizardService").init(tmpDAO, tmpGW) />
			</cfcase>
			<cfcase value="UserService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.User.UserDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.User.UserGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.User.UserService").init(tmpDAO, tmpGW) />
			</cfcase>
            
			<cfcase value="ObjectService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Object.AycObjDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Object.AycObjGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.Object.AycObjService").init(tmpDAO, tmpGW) />
			</cfcase>
			<cfcase value="ObjTypeService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Object.ObjTypeDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Object.ObjTypeGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.Object.ObjTypeService").init(tmpDAO, tmpGW) />
			</cfcase>
			<cfcase value="PermissionService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Object.PermissionDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Object.PermissionGateway").init(variables.configurator.config.dsn) />
                <cfset tmpOTsvc = get("ObjTypeService") />
				<cfreturn createObject("component", "#cfcPath#.cfc.Object.PermissionService").init(tmpDAO, tmpGW, tmpOTsvc) />
			</cfcase>
			<cfcase value="UserPermService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Object.UserPermDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Object.UserPermGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.Object.UserPermService").init(tmpDAO, tmpGW) />
			</cfcase>
			<cfcase value="UserRoleService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.cfc.Object.UserRoleDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.cfc.Object.UserRoleGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.cfc.Object.UserRoleService").init(tmpDAO, tmpGW) />
			</cfcase>
			<cfcase value="FieldInstructorService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.model.fieldInstructor.FieldInstructorDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.model.fieldInstructor.FieldInstructorGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.model.fieldInstructor.FieldInstructorService").init(tmpDAO, tmpGW) />
			</cfcase>
			<cfcase value="AgenciesService">
            	<cfset tmpDAO = createObject("component","#cfcPath#.model.Agency.AgenciesDAO").init(variables.configurator.config.dsn) />
            	<cfset tmpGW = createObject("component","#cfcPath#.model.Agency.AgenciesGateway").init(variables.configurator.config.dsn) />
				<cfreturn createObject("component", "#cfcPath#.model.Agency.AgenciesService").init(tmpDAO, tmpGW) />
			</cfcase>
			
			<cfdefaultcase>
				<cfthrow message="#arguments.name# is not a recognized component.">
			</cfdefaultcase>
		
		</cfswitch>
		
	</cffunction>
	
	<cffunction name="get" returnType="any" output="false">
		<cfargument name="name" type="string" required="true">
		
		<cfif not structKeyExists(variables.instances, arguments.name)>
			<cfset variables.instances[arguments.name] = getComponent(arguments.name)>
		</cfif>
		
		<cfreturn variables.instances[arguments.name]>
	
	</cffunction>

</cfcomponent>

